This is all Kalahad's Work

STEP 4:SCRIPTING
Now we are going to do the hard part of this tut, the script. You should get some coffee or something you will need it!

I've been doing script for a long time so this is fairly easy for me. I'll try to explain every line carefully so that you understand everything that is being done and so that you don't simply copy everything without understanding anything.

Ok, the lines in blue are just to explain the next line so don't write them in your script, the lines in red are to show you an alternate way of doing things and script lines are underline in gray.

First open notepad (I use TextPad) and write these lines. They are the same as in any script (until the Fire_Flak88 thread) so they don't really need any explaining…

// File: Tutorial.scr Title of the file
// Authors: Kalahad Who made it
// Date: 00/00/00 The date you did the script

main:

setcvar "g_scoreboardpic" "none"
level waitTill prespawn
exec global/DMprecache.scr
level.script = maps/dm/Tutorial.scr
exec global/exploder.scr

You need this line in almost every script. It's in there that sounds are set for your map. We will need to modify the ubersound.scr to get the flak88 turning and firing sound working and also for the explosion sound. I will show you how a bit later in this tut.

exec ubersound/ubersound.scr

level waittill spawn

end

Now, the hard part :

This is the part where we make the flak88 work correctly. If you remember we put a setthread "Fire_Flak88" in the trigger in our map. So when the player is passing trough the trigger it calls this thread automatically.
Fire_Flak88:

Now we are going to set some variables. The keyword "local" mean that the variable created with this attribute is local to the thread we are working in. So "local.gun_name" is a variable named "gun_name" that is local to this thread. You put the name of your gun in this variable. In our case it is "Flak88_Num1". Don't forget the "$" before the name or it might not work correctly.
local.gun_name = $Flak88_Num1

Now we’ll create a variable that will be use as the target for the gun. In our case it is the player so we write "$player" (the game engine know what “player” is) but it could be many other things like a tank, a position on the map, your old grandmother…
local.target = $player

So now we have 2 variables, the name of the gun and the name of the target. We have all we need to point the gun at the target. In the next line you can see a "setaimtarget", this is a game function that make the object on the left aim at the object on the right by calling the right animation. So to point the gun on you we use this function with the gun name and the target name like in the next line.
local.gun_name setaimtarget local.target

So now the gun is turning but we have a small problem. A gun like that take some time to turn around (it's heavy you know) and if we don't do anything it will fire before the turning is finish and that doesn't give our map a very realistic look. So we are going to make the next part of the script (the firing) wait a bit while the gun is turning. For this we use "wait(1)", the number in the () is the number of seconds we want to wait. Since our gun won't need to turn more than 30° on both sides (the room is not wide enough for more), 1 second should be enough. You can change it if you have a gun that can turn more (or less) than this one.
wait(1)

Here we are creating two variables, a range and an offset. We don't want the explosion to be always right on top of the player. A gun like that is not always very accurate so we are going to do some random calculations to set the place of the explosion. The range and the offset are two distances from the player that we will use to set (randomly) the place off the explosion. Here is a little drawing I made to explain what are the range and the offset.

So if you look at the next two lines in the script we have this part "96+randomint(128)" for both of them. The '96' is a minimal distance from the player so that the explosion will never be closer than 96 units from him. Don't worry, with the explosion we are going to make 96 units is close enough to kill you (twice over). The other part "randomint(128)" will get an integer (randomly) between 0 and 127. So the explosion will be at a range of 96 + 0 or +1 or +2 …or +127 from the player and it will also be at an offset of 96+ 0 or +1 or +2 …or +127 from the player.

local.range = 96 + randomint(128)
local.offset = 96 + randomint(128)


So now we have a range and an offset for the explosion. Now we need to make the gun fire his shell. We do this by making the game call an animation "fire_scripted". We do this by writing the next line. In the game the gun will get a backward motion from the firing and you will see the fire and smoke coming out off the gun pipe (Cooooool).
local.gun_name anim fire_scripted
You could also use something like this:


Local.gun startfirring
Wait(0.2)
Local.gun stopfirring

Now we must wait again. We don't want the explosion to be at the same time that the gun is firing. To make this realistic we are going to make it a random wait. You could put in any values you like. If you have a gun that is at 1500 feet from the target you could put a higher value.
wait( 0.7 + ( ( randomint( 6 ) ) * 0.1) )

Ok, now we are creating a local variables "A1" that will be the actual final position of the explosion. The next line put the explosion right on top of the player. Here the expression ".origin" is use to get the origin of the local variable name "target".
Local.A1 = local.target.origin

Ok, now we have a position for the explosion (A1) but we still have a small problem. We don't want it to be always on top of the player. So this is where we will use the range and offset variables that we made earlier. The range could be in front (positive X values) or on the back (negative X values) of the target. Same thing for the offset, it could be on the right (positive Y values) or the left (negative Y values) of the player. So, if we don't want the explosion to be always on the back and on the right side of the player we need to do some modification to our range and offset values. Remember that our position is a 3 values set (X Y Z). We won't change the 'z' position because the explosion will always be at ground level with the target in this map. In our map, the offset is on the 'Y' axis and the range is on the 'X' axis. To change the 'X' value of the position we change the local.A1[0] value, to change the 'Y' value of the position we change the local.A1[1] value and to change the 'Z' value of the position we change the local.A1[2] value.
if( (randomint( 100 ) ) < 50 )
local.A1[0] = local.A1[0] + local.range
else
local.A1[0] = local.A1[0] - local.range

if( (randomint( 100 ) ) < 50 )
local.A1[1] = local.A1[1] + local.offset
else
local.A1[1] = local.A1[1] - local.offset

Here is a better (more realistic) way of doing the same thing. I did not put it in the script because I don't want to get into the basic of loops and vectors. You should take a look at this and, if you understand it, you should use it in your script to replace the last 9 lines we wrote. This is the way you should use if you want to deal with the ‘Z’ value of the position

local.vec = vector_normalize ( local.gun_name.origin - ( local.target.origin ) )
local.A1 = vector_scale local.vec local.offset
local. A1 = local. A1 + local.target.origin + ( 0 0 32 )

for ( local.i=0; local.i<2; local.i++ )
{
if ( (randomint 100 ) < 50 )
local. A1 [local.i] = local. A1 [local.i] + randomint( local.range )
else
local. A1 [local.i] = local. A1 [local.i] - randomint( local.range )
}

If you do it this way you will want to use a bigger range value and a bigger offset value, something like "80+randomint(304)"…

Cool, now we have our final position for the explosion, it will be inside a square (with 4 sides of 224 units) around the player position (but not closer than 96 units from him) but we still need an explosion. In the single player maps the game use the bazooka explosion to create the explosion for the flak88. I don't know if you've seen Band of brothers but the flak explosion in the wood near the city of Foy were a lot bigger, so lets make something big for our map. To show you the kind of thing you could make I will use 3 explosions at the same time and on the same spot. The bazooka explosion because it is nice, the mortar (like on dday) because it is big and the mortar in the Higgins boat because it has a lot of fire and a nice ring of smoke. Ok, let's do it. You need to create 3 local variables (I named them Exp1, Exp2, Exp3) and assigned them each to a different animation. You do this by using the 'spawn' keyword and then the name of the animation (and path) you want (between ""). Just like in the next 3 lines.
local.Exp1 = spawn "fx/scriptbazookaexplosion.tik"
local.Exp2 = spawn "animate/fx_mortar_dirt.tik"
local.Exp3 = spawn "animate/fx_mortar_higgins.tik"


Ok so now we have 3 animations for our explosion, but we need something more. What happen when there is an explosion (except dying)? The ground shake!!! We are going to do this by calling "earthquake.scr". You do it just like in the next line. The setting ".23 4 0 0" is great but you could try others by trial and error if you want.
exec global/earthquake.scr .23 4 0 0

Very nice!!! Now we have a gun firing, a position for the explosion, 3 animations for the explosion and a ground that shakes. Very cool, the next thing to do is to set the origin of the 3 animations and start them up. You do that like this…
local.Exp1.origin = local.A1
local.Exp1 anim start

local.Exp2.origin = local.A1
local.Exp2 anim start


local.Exp3.origin = local.A1
local.Exp3 anim start


This is simply another wait before we make the gun turn back in its original position.
wait(1)

The next 3 lines are very important. If we don't do this the effect (damage zone) of the explosion will stay on the map after the animations are gone. So now we must remove the 3 Exp variables (Exp1, Exp2 and Exp3) we used for the explosion.
local.Exp1 remove
local.Exp2 remove
local.Exp3 remove

Note : Some explosion animation have a damage zone with them, some don’t. If you’re using an animation that doesn’t have a damage zone you can set one yourself by writing the next line.

setdamageradius Local.A1.origin 75 200

Where setdamageradius is the game function, Local.A1.origin is the origin of the damage zone, 75 is the amount of damage and 200 is the radius around the origin of the damage zone where the damage is effective.

And now the final detail! Even after firing the gun turret is following the target (if he wasn’t blown out of the map). We want the gun turret to turn back to its original position. So you go back in your map and make a little 8x8 brush near the player start and then put a script origin (right click in the 2D view and select script?origin). Then with it still selected hit 'N' to bring up the entity window and put a targetname(I use FlakBaseAim). So now we do a 'setaimtarget' (like at the beginning of the script but this time on the origin we just create). You could also use an absolute value for this instead of a script?origin…
local.gun_name setaimtarget $FlakBaseAim

You could use the “clearAimTarget” game class to do this but, if you do, the gun will stop following the player but it won’t return in its original position.

end
// Et voilà !!!

Ok, the script is done. Some will say that this script his to complicated for nothing. I tried to make this more simplistic but it doesn't look real enough for me when I play it out. Remember, a nice map his a map that look real. If you want to hit the target right in the face the first time, you simply don't use any random values. You just put the explosions animations at the player position "local.target.origin".

You could do the same thing with a tank turret (with some minor modifications). You could also make random bombing in a field. You simply put a trigger in the field, create more explosion position (with different range and offset) and put them in a loop. From there it is almost only copy and paste… You could also make the gunfire randomly around the trigger instead of the player, this give a chance for the player to get away after he (or she, we never know!) triggers the gunfire. You could also make a trigger that is trigger in only one direction, this way you know which way the player is running and you can fire in front of him to make him stop or change direction… You could even make a trigger that his high enough to be trigger if the player is standing up but not if he is crouching…

© Nemesis's Tutorial Page 2002-2003